home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 52
/
Amiga Format AFCD52 (Issue 136, May 2000).iso
/
-serious-
/
programming
/
other
/
dopus412-gpl
/
dopus_disk
/
diskop.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-02-28
|
18KB
|
766 lines
/*
Directory Opus 4
Original GPL release version 4.12
Copyright 1993-2000 Jonathan Potter
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
All users of Directory Opus 4 (including versions distributed
under the GPL) are entitled to upgrade to the latest version of
Directory Opus version 5 at a reduced price. Please see
http://www.gpsoft.com.au for more information.
The release of Directory Opus 4 under the GPL in NO WAY affects
the existing commercial status of Directory Opus 5.
*/
#include "diskop.h"
void main(argc,argv)
int argc;
char *argv[];
{
struct DOpusRemember *memkey=NULL;
struct VisInfo *vis;
char **dummy_args,*port,*opbuf,*stringname;
struct StringData *stringdata;
int arg;
if (!(DOpusBase=(struct DOpusBase *)OpenLibrary("dopus.library",18)))
#ifdef __SASC_60
__exit(0);
#else
_exit(0);
#endif
if ((vis=LAllocRemember(&memkey,sizeof(struct VisInfo),MEMF_CLEAR)) &&
(dummy_args=LAllocRemember(&memkey,sizeof(char *)*16,MEMF_CLEAR)) &&
(opbuf=LAllocRemember(&memkey,80,MEMF_CLEAR)) &&
(stringname=LAllocRemember(&memkey,80,MEMF_CLEAR)) &&
(stringdata=LAllocRemember(&memkey,sizeof(struct StringData),MEMF_CLEAR))) {
IntuitionBase=DOpusBase->IntuitionBase;
GfxBase=DOpusBase->GfxBase;
IconBase=OpenLibrary("icon.library",0);
if (argc==0) {
struct WBStartup *startup;
int arg;
startup=(struct WBStartup *)argv;
for (arg=0;arg<startup->sm_NumArgs && arg<16;arg++) {
dummy_args[arg]=startup->sm_ArgList[arg].wa_Name;
++argc;
}
argv=dummy_args;
if (IconBase) {
struct DiskObject *dobj;
char *str;
if (dobj=GetDiskObject(argv[0])) {
if (str=FindToolType(dobj->do_ToolTypes,"OPERATION")) {
LStrnCpy(opbuf,str,80);
argv[1]=opbuf;
if (argc<2) argc=2;
}
FreeDiskObject(dobj);
}
}
}
if (argc>1) {
if (argc>2 && argv[2][0]=='&') {
arg=3;
port=&argv[2][1];
}
else {
arg=2;
port=NULL;
}
get_vis_info(vis,port);
stringdata->default_table=default_strings;
stringdata->string_count=STR_STRING_COUNT;
stringdata->min_version=STRING_VERSION;
if (vis->vi_language)
lsprintf(stringname,"DOpus:Modules/S/DM_Disk_%s.STR",vis->vi_language);
else stringname[0]=0;
if (ReadStringFile(stringdata,stringname)) {
string_table=stringdata->string_table;
switch (argv[1][0]) {
case 'f':
case 'F':
diskop_format(vis,port,argc-arg,&argv[arg]);
break;
case 'd':
case 'D':
diskop_diskcopy(vis,port,argc-arg,&argv[arg]);
break;
case 'i':
case 'I':
diskop_install(vis,argc-arg,&argv[arg]);
break;
}
}
FreeStringFile(stringdata);
}
if (IconBase) CloseLibrary(IconBase);
}
LFreeRemember(&memkey);
CloseLibrary((struct Library *)DOpusBase);
#ifdef __SASC_60
__exit(0);
#else
_exit(0);
#endif
}
void get_vis_info(vis,portname)
struct VisInfo *vis;
char *portname;
{
vis->vi_fg=1; vis->vi_bg=0;
vis->vi_shine=2; vis->vi_shadow=1;
vis->vi_font=NULL;
vis->vi_screen=NULL;
vis->vi_stringcol[0]=1; vis->vi_stringcol[1]=0;
vis->vi_activestringcol[0]=1; vis->vi_activestringcol[1]=0;
vis->vi_flags=VISF_WINDOW;
vis->vi_language=NULL;
if (dopus_message(DOPUSMSG_GETVIS,(APTR)vis,portname)) return;
if (IntuitionBase->LibNode.lib_Version>35) {
struct DrawInfo *drinfo;
struct Screen *pub;
if (pub=LockPubScreen(NULL)) {
drinfo=GetScreenDrawInfo(pub);
vis->vi_shine=drinfo->dri_Pens[SHINEPEN];
vis->vi_shadow=drinfo->dri_Pens[SHADOWPEN];
vis->vi_fg=drinfo->dri_Pens[TEXTPEN];
vis->vi_bg=drinfo->dri_Pens[BACKGROUNDPEN];
FreeScreenDrawInfo(pub,drinfo);
UnlockPubScreen(NULL,pub);
}
}
}
dopus_message(cmd,data,portname)
int cmd;
APTR data;
char *portname;
{
struct MsgPort *port,*replyport;
struct DOpusMessage msg;
Forbid();
if (portname && portname[0] &&
(port=FindPort(portname)) &&
(replyport=LCreatePort(NULL,0))) {
msg.msg.mn_Node.ln_Type=NT_MESSAGE;
msg.msg.mn_Node.ln_Name=NULL;
msg.msg.mn_ReplyPort=replyport;
msg.msg.mn_Length=(UWORD)sizeof(struct DOpusMessage);
msg.command=cmd;
msg.data=data;
PutMsg(port,(struct Message *)&msg);
Permit();
WaitPort(replyport);
GetMsg(replyport);
LDeletePort(replyport);
return(1);
}
Permit();
return(0);
}
void fill_out_req(req,vis)
struct RequesterBase *req;
struct VisInfo *vis;
{
req->rb_fg=vis->vi_fg;
req->rb_bg=vis->vi_bg;
req->rb_shine=vis->vi_shine;
req->rb_shadow=vis->vi_shadow;
req->rb_font=vis->vi_font;
req->rb_flags&=~RBF_WINDOWCENTER;
if (vis->vi_screen) {
if (vis->vi_flags&VISF_WINDOW) {
req->rb_screen=((struct Window *)vis->vi_screen)->WScreen;
req->rb_window=(struct Window *)vis->vi_screen;
req->rb_flags|=RBF_WINDOWCENTER;
}
else req->rb_screen=vis->vi_screen;
}
else req->rb_screen=NULL;
}
struct Gadget *addreqgadgets(reqbase,gadgets,mask,count)
struct RequesterBase *reqbase;
struct TagItem **gadgets;
int mask,*count;
{
int gad;
struct Gadget *gadget=NULL,*newgadget,*firstgadget;
for (gad=0;;gad++) {
if (!gadgets[gad]) break;
if (!(mask&(1<<gad))) {
if (!(newgadget=(struct Gadget *)
AddRequesterObject(reqbase,gadgets[gad]))) return(NULL);
if (gadget) gadget->NextGadget=newgadget;
else firstgadget=newgadget;
gadget=newgadget;
++*count;
}
}
AddGadgets(reqbase->rb_window,firstgadget,NULL,gad,reqbase->rb_shine,reqbase->rb_shadow,1);
return(firstgadget);
}
int error_rets[]={1,0};
check_error(reqbase,str,gadtxt)
struct RequesterBase *reqbase;
char *str;
int gadtxt;
{
struct DOpusSimpleRequest req;
char *error_gads[3];
req.text=str;
error_gads[0]=string_table[gadtxt];
error_gads[1]=string_table[STR_CANCEL];
error_gads[2]=NULL;
req.gads=error_gads;
req.rets=error_rets;
req.hi=reqbase->rb_shine;
req.lo=reqbase->rb_shadow;
req.fg=reqbase->rb_fg;
req.bg=reqbase->rb_bg;
req.strbuf=NULL;
req.flags=SRF_RECESSHI;
if (reqbase->rb_flags&RBF_BORDERS) req.flags|=SRF_BORDERS;
req.font=reqbase->rb_font;
req.title="DOpus_Disk";
return(DoSimpleRequest(reqbase->rb_window,&req));
}
ULONG do_checksum(sector)
ULONG *sector;
{
ULONG sum;
int i;
for (sum=0,i=0;i<(TD_SECTOR>>2);i++) sum+=sector[i];
return(sum);
}
do_writeblock(device_req,buffer,offset)
struct IOExtTD *device_req;
APTR buffer;
ULONG offset;
{
device_req->iotd_Req.io_Command=CMD_WRITE;
device_req->iotd_Req.io_Data=buffer;
device_req->iotd_Req.io_Length=TD_SECTOR;
device_req->iotd_Req.io_Offset=offset*TD_SECTOR;
return((int)DoIO((struct IORequest *)device_req));
}
void inhibit_drive(device,state)
char *device;
ULONG state;
{
struct MsgPort *handler;
if (DOSBase->dl_lib.lib_Version<36) {
if (handler=(struct MsgPort *)DeviceProc(device))
SendPacket(handler,ACTION_INHIBIT,&state,1);
}
else Inhibit(device,state);
}
void border_text(reqbase,border,infobuf)
struct RequesterBase *reqbase;
Object_Border *border;
char *infobuf;
{
struct RastPort *rp;
rp=reqbase->rb_window->RPort;
SetAPen(rp,reqbase->rb_bg);
RectFill(rp,border->ob_left,border->ob_top,
border->ob_left+border->ob_width-1,border->ob_top+border->ob_height-1);
SetAPen(rp,reqbase->rb_fg);
if (infobuf) {
ObjectText(reqbase,
border->ob_left,
border->ob_top,
border->ob_width,
border->ob_height,
infobuf,
TEXTPOS_CENTER|TEXTPOS_F_NOUSCORE);
}
}
struct DeviceNode *find_device(name)
char *name;
{
struct RootNode *rootnode;
struct DosInfo *dosinfo;
struct DeviceNode *devnode;
char matchname[32],devname[32];
int a;
if (!name) return(NULL);
for (a=0;name[a];a++) {
if (name[a]==':') break;
matchname[a]=name[a];
}
matchname[a]=0;
Forbid();
rootnode=(struct RootNode *) DOSBase->dl_Root;
dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
while (devnode) {
if (devnode->dn_Type==DLT_DEVICE && devnode->dn_Task) {
BtoCStr((BPTR)devnode->dn_Name,devname,32);
if (strcmp(devname,matchname)==0) {
Permit();
return(devnode);
}
}
devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
}
Permit();
return(NULL);
}
char **get_device_list(key,alike)
struct DOpusRemember **key;
char *alike;
{
struct RootNode *rootnode;
struct DosInfo *dosinfo;
struct DeviceNode *devnode,*alikenode=NULL;
int count=1;
char **listtable,devname[32];
if (alike) alikenode=find_device(alike);
Forbid();
rootnode=(struct RootNode *) DOSBase->dl_Root;
dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
while (devnode) {
if (devnode->dn_Type==DLT_DEVICE && devnode->dn_Task &&
devnode->dn_Startup>512) {
if (!alikenode || like_devices(devnode,alikenode))
++count;
}
devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
}
if (listtable=LAllocRemember(key,count*4,MEMF_CLEAR)) {
devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
count=0;
while (devnode) {
if (devnode->dn_Type==DLT_DEVICE && devnode->dn_Task &&
devnode->dn_Startup>512) {
if (!alikenode || like_devices(devnode,alikenode)) {
BtoCStr((BPTR)devnode->dn_Name,devname,32);
strcat(devname,":");
if (listtable[count]=LAllocRemember(key,strlen(devname)+1,0))
strcpy(listtable[count],devname);
++count;
}
}
devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
}
sort_device_list(listtable);
}
Permit();
return(listtable);
}
void sort_device_list(table)
char **table;
{
int count,gap,i,j;
char *temp;
for (count=0;table[count];count++);
for (gap=count/2;gap>0;gap/=2)
for (i=gap;i<count;i++)
for (j=i-gap;j>=0;j-=gap) {
if (LStrCmpI(table[j],table[j+gap])<=0) break;
temp=table[j];
table[j]=table[j+gap];
table[j+gap]=temp;
}
}
check_disk(reqbase,device_req,name,prot)
struct RequesterBase *reqbase;
struct IOExtTD *device_req;
char *name;
int prot;
{
char errorbuf[80];
FOREVER {
device_req->iotd_Req.io_Command=TD_CHANGESTATE;
DoIO((struct IORequest *)device_req);
if (device_req->iotd_Req.io_Actual) {
lsprintf(errorbuf,string_table[STR_NODISKPRESENT],name);
if (!(check_error(reqbase,errorbuf,STR_RETRY))) return(0);
}
else break;
}
if (prot) {
FOREVER {
device_req->iotd_Req.io_Command=TD_PROTSTATUS;
DoIO((struct IORequest *)device_req);
if (device_req->iotd_Req.io_Actual) {
lsprintf(errorbuf,string_table[STR_DISKWRITEPROTECTED],name);
if (!(check_error(reqbase,errorbuf,STR_RETRY))) return(0);
}
else break;
}
}
return(1);
}
check_abort(window)
struct Window *window;
{
struct IntuiMessage *msg;
int abort=0;
while (msg=(struct IntuiMessage *)GetMsg(window->UserPort)) {
if (msg->Class==IDCMP_MOUSEBUTTONS && msg->Code==MENUDOWN)
abort=1;
ReplyMsg((struct Message *)msg);
}
return(abort);
}
check_blank_disk(reqbase,device,action)
struct RequesterBase *reqbase;
char *device,*action;
{
BPTR lock;
struct InfoData __aligned info;
struct FileInfoBlock __aligned fib;
struct Process *myproc;
APTR wsave;
char blank=0,*message,diskname[40],sizebuf[20];
int ret=1;
if (!(message=AllocMem(400,MEMF_CLEAR))) return(1);
myproc=(struct Process *)FindTask(NULL);
wsave=myproc->pr_WindowPtr;
myproc->pr_WindowPtr=(APTR)-1;
if (lock=Lock(device,ACCESS_READ)) {
Info(lock,&info);
switch (info.id_DiskType) {
case ID_UNREADABLE_DISK:
case ID_NOT_REALLY_DOS:
blank=1;
break;
default:
Examine(lock,&fib);
strcpy(diskname,fib.fib_FileName);
if (!(ExNext(lock,&fib))) blank=1;
break;
}
UnLock(lock);
}
else blank=1;
myproc->pr_WindowPtr=wsave;
if (!blank && action) {
getsizestring(sizebuf,info.id_NumBlocksUsed*info.id_BytesPerBlock);
lsprintf(message,string_table[STR_DISK_NOT_BLANK],
device,diskname,sizebuf,action);
if (!(check_error(reqbase,message,STR_PROCEED))) ret=0;
}
FreeMem(message,400);
return(ret);
}
void set_env(action,gadget,count,list)
char *action;
struct Gadget *gadget;
int count;
struct DOpusListView *list;
{
int file,listid='LIST';
UWORD len;
char envname[80],null=0;
lsprintf(envname,"ENV:DOpus_%s.prefs",action);
if (!(file=Open(envname,MODE_NEWFILE))) return;
while (gadget && count--) {
if (gadget->Activation&GACT_TOGGLESELECT) {
Write(file,&gadget->GadgetID,sizeof(UWORD));
Write(file,&gadget->GadgetType,sizeof(UWORD));
switch (gadget->GadgetType) {
case GTYP_BOOLGADGET:
Write(file,&gadget->Flags,sizeof(UWORD));
break;
case GTYP_STRGADGET:
len=strlen(((struct StringInfo *)gadget->SpecialInfo)->Buffer)+1;
Write(file,&len,sizeof(UWORD));
Write(file,((struct StringInfo *)gadget->SpecialInfo)->Buffer,len);
if (len%2) Write(file,&null,1);
break;
}
}
else ++count;
gadget=gadget->NextGadget;
}
while (list) {
Write(file,&listid,sizeof(ULONG));
Write(file,list->items[list->itemselected],
(len=(strlen(list->items[list->itemselected])+1)));
if (len%2) Write(file,&null,1);
list=list->next;
}
Close(file);
}
void get_env(action,firstgadget,count,list)
char *action;
struct Gadget *firstgadget;
int count;
struct DOpusListView *list;
{
int file,size,a,b,*lbuf;
char envname[80],*nptr;
struct Gadget *gadget;
UWORD gadgettype,gadgetid,len,*buf;
lsprintf(envname,"ENV:DOpus_%s.prefs",action);
if (!(file=Open(envname,MODE_OLDFILE))) return;
Seek(file,0,OFFSET_END);
size=Seek(file,0,OFFSET_BEGINNING);
if (!(buf=(UWORD *)AllocMem(size,MEMF_CLEAR))) {
Close(file);
return;
}
Read(file,(char *)buf,size);
Close(file);
for (a=0;a<size/2;) {
lbuf=(int *)&buf[a];
if (lbuf[0]=='LIST') {
a+=2;
nptr=(char *)&buf[a];
if (list) {
for (b=0;list->items[b];b++) {
if (LStrCmpI(nptr,list->items[b])==0) {
list->itemselected=b;
break;
}
}
list=list->next;
}
b=strlen(nptr)+1;
if (b%2) ++b;
a+=b/2;
continue;
}
gadgetid=buf[a++];
gadgettype=buf[a++];
gadget=firstgadget;
while (gadget) {
if (gadget->GadgetID==gadgetid && gadget->GadgetType==gadgettype)
break;
gadget=gadget->NextGadget;
}
if (!count--) gadget=NULL;
switch (gadgettype) {
case GTYP_BOOLGADGET:
if (gadget) gadget->Flags=buf[a];
++a;
break;
case GTYP_STRGADGET:
len=buf[a++];
if (gadget) strcpy(((struct StringInfo *)gadget->SpecialInfo)->Buffer,(char *)&buf[a]);
if (len%2) ++len;
a+=len/2;
break;
}
}
FreeMem(buf,size);
}
void fix_listview(reqbase,list)
struct RequesterBase *reqbase;
struct DOpusListView *list;
{
list->window=reqbase->rb_window;
list->flags|=DLVF_LEAVE|DLVF_SLOW;
list->sliderwidth=8;
list->slidercol=reqbase->rb_fg;
list->sliderbgcol=reqbase->rb_bg;
list->textcol=reqbase->rb_fg;
list->boxhi=reqbase->rb_shine;
list->boxlo=reqbase->rb_shadow;
list->arrowfg=reqbase->rb_fg;
list->arrowbg=reqbase->rb_bg;
list->itemfg=reqbase->rb_fg;
list->itembg=reqbase->rb_bg;
}
void select_device(list,exclude)
struct DOpusListView *list;
char *exclude;
{
int def=-1,item;
for (item=0;list->items[item];item++) {
if (!exclude || LStrCmpI(list->items[item],exclude)) {
if (list->items[item][0]=='D' &&
list->items[item][1]=='F' &&
list->items[item][3]==':') {
def=item;
break;
}
if (def==-1) def=item;
}
}
if (def==-1) def=0;
list->itemselected=def;
list->topitem=def;
}
like_devices(node,likenode)
struct DeviceNode *node,*likenode;
{
struct DosEnvec *envec,*likeenvec;
struct FileSysStartupMsg *startup,*likestartup;
startup=(struct FileSysStartupMsg *)BADDR(node->dn_Startup);
likestartup=(struct FileSysStartupMsg *)BADDR(likenode->dn_Startup);
envec=(struct DosEnvec *)BADDR(startup->fssm_Environ);
likeenvec=(struct DosEnvec *)BADDR(likestartup->fssm_Environ);
if (envec->de_SizeBlock!=likeenvec->de_SizeBlock ||
envec->de_Surfaces!=likeenvec->de_Surfaces ||
envec->de_BlocksPerTrack!=likeenvec->de_BlocksPerTrack ||
((envec->de_HighCyl-envec->de_LowCyl))!=
((likeenvec->de_HighCyl-likeenvec->de_LowCyl)))
return(0);
return(1);
}
open_device(device,handle)
char *device;
struct DeviceHandle *handle;
{
struct DeviceNode *devnode;
char devicename[40];
handle->startup=NULL;
handle->dosenvec=NULL;
handle->device_port=NULL;
handle->device_req=NULL;
if (!device || !(devnode=find_device(device))) return(0);
handle->startup=(struct FileSysStartupMsg *)BADDR(devnode->dn_Startup);
handle->dosenvec=(struct DosEnvec *)BADDR(handle->startup->fssm_Environ);
BtoCStr((BPTR)handle->startup->fssm_Device,devicename,40);
if (!(handle->device_port=LCreatePort(NULL,0))) return(0);
if (handle->device_req=(struct IOExtTD *)
LCreateExtIO(handle->device_port,sizeof(struct IOExtTD))) {
if (!(OpenDevice(devicename,handle->startup->fssm_Unit,
(struct IORequest *)handle->device_req,handle->startup->fssm_Flags)))
return(1);
LDeleteExtIO((struct IORequest *)handle->device_req);
handle->device_req=NULL;
}
return(0);
}
void close_device(handle)
struct DeviceHandle *handle;
{
if (handle->device_req) {
CloseDevice((struct IORequest *)handle->device_req);
LDeleteExtIO((struct IORequest *)handle->device_req);
handle->device_req=NULL;
}
if (handle->device_port) {
LDeletePort(handle->device_port);
handle->device_port=NULL;
}
}
void drive_motor(req,state)
struct IOExtTD *req;
int state;
{
req->iotd_Req.io_Command=TD_MOTOR;
req->iotd_Req.io_Length=state;
DoIO((struct IORequest *)req);
}
void show_sel_item(list)
struct DOpusListView *list;
{
while (list) {
if (list->itemselected<list->topitem ||
list->itemselected>(list->topitem+list->lines-1)) {
list->topitem=list->itemselected;
RefreshListView(list,1);
}
list=list->next;
}
}